package cn.iocoder.yudao.module.wine.service.messageboard;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.wine.controller.admin.messageboard.vo.MessageBoardPageReqVO;
import cn.iocoder.yudao.module.wine.controller.admin.messageboard.vo.MessageBoardRespVO;
import cn.iocoder.yudao.module.wine.controller.admin.messageboard.vo.MessageBoardSaveReqVO;
import cn.iocoder.yudao.module.wine.utils.SnowflakeIdGeneratorUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.wine.controller.app.messageboard.vo.*;
import cn.iocoder.yudao.module.wine.dal.dataobject.messageboard.MessageBoardDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.wine.dal.mysql.messageboard.MessageBoardMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wine.enums.ErrorCodeConstants.*;

/**
 * 用户留言板 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class MessageBoardServiceImpl implements MessageBoardService {

    @Resource
    private MessageBoardMapper messageBoardMapper;

    @Resource
    private MemberUserApi userApi;

    @Override
    public Long createMessageBoard(MessageBoardSaveReqVO createReqVO) {
        // 插入
        MessageBoardDO messageBoard = BeanUtils.toBean(createReqVO, MessageBoardDO.class);
        messageBoardMapper.insert(messageBoard);
        // 返回
        return messageBoard.getId();
    }

    @Override
    public void updateMessageBoard(MessageBoardSaveReqVO updateReqVO) {
        // 校验存在
        validateMessageBoardExists(updateReqVO.getId());
        // 更新
        MessageBoardDO updateObj = BeanUtils.toBean(updateReqVO, MessageBoardDO.class);
        messageBoardMapper.updateById(updateObj);
    }

    @Override
    public void deleteMessageBoard(Long id) {
        // 校验存在
        validateMessageBoardExists(id);
        // 删除
        messageBoardMapper.deleteById(id);
    }

    private void validateMessageBoardExists(Long id) {
        if (messageBoardMapper.selectById(id) == null) {
            throw exception(INFO_NOT_EXISTS);
        }
    }

    @Override
    public MessageBoardDO getMessageBoard(Long id) {
        return messageBoardMapper.selectById(id);
    }

    @Override
    public PageResult<MessageBoardRespVO> getMessageBoardPage(MessageBoardPageReqVO pageReqVO) {
        return messageBoardMapper.selectPage(pageReqVO);
    }


    @Override
    public Long appCreateMessageBoard(AppMessageBoardSaveReqVO createReqVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        Long chatId = validateMessageBoardByUserIdExists(loginUserId, createReqVO.getReceiveId());
        if (chatId != null) {
            createReqVO.setChatId(chatId);
        } else {
            createReqVO.setChatId(SnowflakeIdGeneratorUtil.generateLongId());
        }
        createReqVO.setSendId(loginUserId);
        // 插入
        MessageBoardDO messageBoard = BeanUtils.toBean(createReqVO, MessageBoardDO.class);
        messageBoardMapper.insert(messageBoard);
        // 返回
        return messageBoard.getId();
    }

    @Override
    public void createOrderMessageBoard(MessageBoardSaveReqVO messageBoardSaveReqVO) {
        Long chatId = validateMessageBoardByUserIdExists(messageBoardSaveReqVO.getSendId(), messageBoardSaveReqVO.getReceiveId());
        if (chatId != null) {
            messageBoardSaveReqVO.setChatId(chatId);
        }
        // 插入
        MessageBoardDO messageBoard = BeanUtils.toBean(messageBoardSaveReqVO, MessageBoardDO.class);
        messageBoardMapper.insert(messageBoard);

    }

    @Override
    public Long getChatId(Long buyUserId, Long saleUserId) {
        return messageBoardMapper.getChatId(buyUserId,saleUserId);
    }

    @Override
    public List<AppMessageBoardRespVO> appGetMessageBoardDialog(AppMessageBoardPageReqVO pageReqVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        List<AppMessageBoardRespVO> respVOS = messageBoardMapper.appSelectMessageBoardDialog(pageReqVO);
        if (CollectionUtil.isEmpty(respVOS)) {
            return respVOS;
        }

        return respVOS.stream().peek(item -> {
            MemberUserRespDTO user;
            if (item.getSendId().equals(loginUserId)) {
                user = userApi.getUser(item.getReceiveId());
            } else {
                user = userApi.getUser(item.getSendId());
            }
            if (user != null) {
                item.setAvatar(user.getAvatar());
                item.setNickname(user.getNickname());
            }
        }).collect(Collectors.toList());
    }


    @Override
    public List<MessageBoardDO> appGetMessageBoardList(AppMessageBoardContentListReqVO listReqVO) {
        return messageBoardMapper.selectContentList(listReqVO);
    }

    @Override
    public List<MessageBoardDO> appSupplyGetMessageBoardList(AppSupplyMessageBoardReqVO reqVO) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        List<MessageBoardDO> list = messageBoardMapper.selectList(new MPJLambdaWrapperX<MessageBoardDO>()
                .eqIfExists(MessageBoardDO::getSendId, loginUserId)
                .eqIfExists(MessageBoardDO::getReceiveId, reqVO.getUserId())
                .or()
                .eqIfExists(MessageBoardDO::getSendId, reqVO.getUserId())
                .eqIfExists(MessageBoardDO::getReceiveId, loginUserId)
                .orderByDesc(MessageBoardDO::getCreateTime));
        return list;
    }


    /**
     * 校验数据库中是否存在聊天记录
     *
     * @param sendId
     * @param receiveId
     * @return
     */
    private Long validateMessageBoardByUserIdExists(Long sendId, Long receiveId) {
        List<MessageBoardDO> list = messageBoardMapper.selectList(new LambdaQueryWrapperX<MessageBoardDO>()
                .eqIfPresent(MessageBoardDO::getSendId, sendId)
                .eqIfPresent(MessageBoardDO::getReceiveId, receiveId)
                .or(wrapper -> {
                    wrapper.eq(MessageBoardDO::getSendId, receiveId)
                            .eq(MessageBoardDO::getReceiveId, sendId);
                }));
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        return list.get(0).getChatId();
    }

}
